home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostu2 / gouraud2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-11-23  |  8.7 KB  |  535 lines

  1. PROGRAM gouraud2;
  2. {
  3.     Gouraud shading or what? Part 2!
  4.     - by Bjarke Viksφe
  5.     aug 1994
  6. }
  7.  
  8. {{$DEFINE DEBUG}
  9.  
  10. USES
  11.     DEMOINIT;
  12.  
  13. CONST
  14.     NUMBER_FACES = 6;
  15.     NUMBER_COORDS = 8;
  16.     box = 110; {size of box}
  17.  
  18. TYPE
  19.     SlopeType = array[0..320*2] of integer;
  20.  
  21.     FaceType = RECORD
  22.         l1,l2,l3,l4 : byte;
  23.     end;
  24.  
  25.  
  26. VAR
  27.     slope,zslope : SlopeType;
  28.     face : array[1..NUMBER_FACES] of FaceType;
  29.     cbuffer : array[0..NUMBER_COORDS*4-1] of integer;
  30.  
  31.     minx,maxx : integer;
  32.  
  33.     sinustabel : array[0..639] of integer;
  34.     v1,v2,v3 : word;
  35.     cos1,sin1,cos2,sin2,cos3,sin3 : integer;
  36.  
  37.  
  38. CONST
  39.     display1 : word = $0000;
  40.     display2 : word = $4000;
  41.     {setup coords for a box}
  42.     coords : array[0..NUMBER_COORDS*3-1] of integer =
  43.         (box,box,-box, -box,box,-box, -box,-box,-box, box,-box,-box,
  44.         box,box,box, -box,box,box, -box,-box,box, box,-box,box);
  45.  
  46.  
  47. (*------------------------------------------------*)
  48.  
  49. procedure SetupSinus;
  50. var
  51.     i : integer;
  52.     v, vadd : real;
  53. begin
  54.     v:=0.0;
  55.     vadd:=(2.0*pi/512.0);
  56.     for i:=0 to 639 do begin
  57.         sinustabel[i]:=round(sin(v)*32767);
  58.         v:=v+vadd;
  59.     end;
  60. end;
  61.  
  62. procedure SetupFaces;
  63. {setup faces. Make sure face keeps track of which coordinates it uses!}
  64. begin
  65.     with face[1] do begin l1:=3; l2:=2; l3:=1; l4:=0; end;
  66.     with face[2] do begin l1:=4; l2:=5; l3:=6; l4:=7; end;
  67.     with face[3] do begin l1:=0; l2:=1; l3:=5; l4:=4; end;
  68.     with face[4] do begin l1:=1; l2:=2; l3:=6; l4:=5; end;
  69.     with face[5] do begin l1:=2; l2:=3; l3:=7; l4:=6; end;
  70.     with face[6] do begin l1:=3; l2:=0; l3:=4; l4:=7; end;
  71. end;
  72.  
  73. procedure InitDemo;
  74. var
  75.     i : integer;
  76. begin
  77.     Screen_Off;
  78.     ClearWholeScreen;
  79.     SetupSinus;
  80.     SetupFaces;
  81.  
  82.     v1:=0; v2:=0; v3:=0;
  83.  
  84.     for i:=1 to 63 do SetRGB(i,0,64-i,0);
  85.     for i:=64 to 255 do SetRGB(i,0,0,0);
  86.  
  87.     Screen_On;
  88. end;
  89.  
  90.  
  91. (*------------------------------------------------*)
  92.  
  93. procedure SwapDisplay;
  94. var
  95.     temp : word;
  96. begin
  97.     temp:=display2;
  98.     display2:=display1;
  99.     display1:=temp;
  100.     SetAddress(Ptr(SEGA000,display2));
  101. end;
  102.  
  103. procedure ClearScreen; assembler;
  104. asm
  105.     mov    dx,$3C4
  106.     mov    ax,$0F02
  107.     out    dx,ax
  108.  
  109.     mov    es,SEGA000
  110.     mov    di,display1
  111.     add    di,(30*WIDTH)+16
  112.     mov    dx,140
  113.     xor ax,ax
  114.     mov    bx,48/2
  115. @loop:
  116.     mov    cx,bx
  117.     rep stosw
  118.     add    di,WIDTH-48
  119.     dec    dl
  120.     jnz    @loop
  121. end;
  122.  
  123.  
  124. (*------------------------------------------------*)
  125.  
  126. procedure ClearSlope; assembler;
  127. asm
  128.     mov    ax,ds
  129.     mov    es,ax
  130.     lea    di,slope
  131.     DB LONG; mov ax,$8000; DW $8000;
  132.     cld
  133.     mov    cx,TYPE(slopetype)/4
  134.     rep; DB LONG; stosw
  135. end;
  136.  
  137.  
  138. procedure CalcSlope(l1,l2 : integer); assembler;
  139. var
  140.     z1,z2,coladd : word;
  141.     xlowadd : word;
  142.     ysize : integer;
  143. asm
  144.     lea    si,cbuffer
  145.     DB LONG; xor cx,cx
  146.     mov    bx,l1                    {get first coords}
  147.     shl    bx,3
  148.     mov    ax,[si+bx+4]        {get z value}
  149.     mov    z2,ax
  150.     mov    dx,[si+bx]            {get x/y coords}
  151.     mov    cx,[si+bx+2]
  152.  
  153.     mov    ax,l2                    {get second coords}
  154.     shl    ax,3
  155.     add    si,ax
  156.     mov    ax,[si+4]            {get z value}
  157.     mov    z1,ax
  158.     mov    ax,[si]                {get x/y coords}
  159.     mov    bx,[si+2]
  160.  
  161.     cmp    bx,cx                    {make sure we go downwards...}
  162.     jle    @noswap
  163.     mov    si,z1                    {swap z}
  164.     xchg    z2,si
  165.     mov    z1,si
  166.     xchg    ax,dx                    {swap x}
  167.     xchg    bx,cx                    {sway y}
  168. @noswap:
  169.  
  170.     cmp    bx,minx                {record miny and maxy}
  171.     jae    @minx
  172.     mov    minx,bx
  173. @minx:
  174.     cmp    cx,maxx
  175.     jbe    @maxx
  176.     mov    maxx,cx
  177. @maxx:
  178.  
  179.     sub    cx,bx                    {find y-size}
  180.     jcxz    @zero
  181.     mov    ysize,cx
  182.     add    bx,bx
  183.     add    bx,bx
  184.     lea    si,slope
  185.     add    si,bx
  186.  
  187.     push    ax
  188.     sub    dx,ax
  189.  
  190.     mov    ax,dx                    {calc x-slope run}
  191.     DB LONG; shl    ax,16
  192.     {cdq} DB $66,$99
  193.     DB LONG; idiv    cx
  194.     DB LONG; mov    dx,ax
  195.     DB LONG; shr    dx,16
  196.     mov    xlowadd,ax
  197.     {DX also loaded... but kept alive}
  198.  
  199.     push    dx                        {also calc z-slope run}
  200.     mov    dh,BYTE PTR z1
  201.     mov    ah,BYTE PTR z2
  202.     sub    ah,dh
  203.     xor    al,al
  204.     cwd
  205.     idiv    cx
  206.     mov    coladd,ax
  207.     pop    dx
  208. @one:
  209.     pop    cx
  210.  
  211.     xor    bx,bx
  212.     mov    ah,BYTE PTR z1    {prepare also z-slope calc. z1:=z1*256}
  213.     xor    al,al
  214.     mov    di,$8000
  215. @loop:
  216.     cmp    [si],di                            {is first slot filled?}
  217.     jne    @other                            {yes, put it in 2nd}
  218.     mov    [si+TYPE(SlopeType)],ah        {insert z-coord}
  219.     mov    [si],cx                            {insert x-coord}
  220.     add    bx,xlowadd                        {add to x-coord}
  221.     adc    cx,dx
  222.     add    ax,coladd                        {add to z-coord}
  223.     add    si,4                                {next slot...}
  224.     dec    ysize
  225.     jnz    @loop
  226.     jmp    NEAR PTR @zero
  227. @other:
  228.     mov    [si+TYPE(SlopeType)+2],ah
  229.     mov    [si+2],cx
  230.     add    bx,xlowadd
  231.     adc    cx,dx
  232.     add    ax,coladd
  233.     add    si,4
  234.     dec    ysize
  235.     jnz    @loop
  236. @zero:
  237. end;
  238.  
  239.  
  240. (*------------------------------------------------*)
  241.  
  242. procedure CalcAngle;
  243. begin
  244.     sin1:=sinustabel[v1]; cos1:=sinustabel[v1+128];
  245.     sin2:=sinustabel[v2]; cos2:=sinustabel[v2+128];
  246.     sin3:=sinustabel[v3]; cos3:=sinustabel[v3+128];
  247.     v1:=(v1+2) AND 511;
  248.     v2:=(v2-1) AND 511;
  249.     v3:=(v3+1) AND 511;
  250. end;
  251.  
  252. procedure RotateAllCoords; assembler;
  253. {Rotate all coords in "coords" around all 3 axis and make
  254.  perspective calcualtion. Store x,y,z results in "cbuffer"}
  255. var
  256.     xkoord,ykoord,zkoord, n : integer;
  257. asm
  258.     mov    ax,ds
  259.     mov    es,ax
  260.     lea    si,coords
  261.     lea    di,cbuffer
  262.     mov    n,NUMBER_COORDS
  263.     cld
  264. @loop:
  265.     lodsw
  266.     mov    xkoord,ax
  267.     lodsw
  268.     mov    ykoord,ax
  269.     lodsw
  270.     mov    zkoord,ax
  271.  
  272.     mov    ax,xkoord               {rotate around Z-axis}
  273.     push    ax
  274.     imul    Cos1
  275.     add    ax,ax
  276.     adc    dx,dx
  277.     mov    bx,dx
  278.     mov    ax,ykoord
  279.     imul    Sin1
  280.     add    ax,ax
  281.     adc    dx,dx
  282.     sub    bx,dx
  283.     mov    xkoord,bx
  284.     pop    ax
  285.     imul    Sin1
  286.     add    ax,ax
  287.     adc    dx,dx
  288.     mov    bx,dx
  289.     mov    ax,ykoord
  290.     imul    Cos1
  291.     add    ax,ax
  292.     adc    dx,dx
  293.     add    bx,dx
  294.     mov    ykoord,bx
  295.  
  296.     mov    ax,ykoord               {rotate around Y-axis}
  297.     push    ax
  298.     imul    Cos2
  299.     add    ax,ax
  300.     adc    dx,dx
  301.     mov    bx,dx
  302.     mov    ax,zkoord
  303.     imul    Sin2
  304.     add    ax,ax
  305.     adc    dx,dx
  306.     sub    bx,dx
  307.     mov    ykoord,bx
  308.     pop    ax
  309.     imul    Sin2
  310.     add    ax,ax
  311.     adc    dx,dx
  312.     mov    bx,dx
  313.     mov    ax,zkoord
  314.     imul    Cos2
  315.     add    ax,ax
  316.     adc    dx,dx
  317.     add    bx,dx
  318.     mov    zkoord,bx
  319.  
  320.     mov    ax,xkoord               {rotate around X-axis}
  321.     push    ax
  322.     imul    Cos3
  323.     add    ax,ax
  324.     adc    dx,dx
  325.     mov    bx,dx
  326.     mov    ax,zkoord
  327.     imul    Sin3
  328.     add    ax,ax
  329.     adc    dx,dx
  330.     sub   bx,dx
  331.     mov    xkoord,bx
  332.     pop    ax
  333.     imul    Sin3
  334.     add    ax,ax
  335.     adc    dx,dx
  336.     mov    bx,dx
  337.     mov    ax,zkoord
  338.     imul    Cos3
  339.     add    ax,ax
  340.     adc    dx,dx
  341.     add    bx,dx
  342.     mov    zkoord,bx
  343.  
  344.     add    bx,800
  345.     and    bx,bx
  346.     jnz    @zero
  347.     mov    bl,1
  348. @zero:
  349.  
  350.     mov    ax,xkoord
  351.     cwd
  352.     mov    dl,ah
  353.     mov    ah,al
  354.     xor    al,al
  355.     idiv    bx
  356.     add    ax,100
  357.     stosw
  358.  
  359.     mov    ax,ykoord
  360.     cwd
  361.     mov    dl,ah
  362.     mov    ah,al
  363.     xor    al,al
  364.     idiv    bx
  365.     add    ax,160
  366.     stosw
  367.  
  368.     mov    ax,bx
  369.     sub    ax,390
  370.     shr    ax,2
  371.     stosw
  372.     add    di,2
  373.  
  374.     dec    n
  375.     jnz    @loop
  376. end;
  377.  
  378.  
  379.  
  380. function FaceShown(l1,l2,l3 : byte) : boolean;
  381. var
  382.     a,b : longint;
  383. begin
  384.     a := longmul(cbuffer[l1]-cbuffer[l2],cbuffer[l3+1]-cbuffer[l2+1]);
  385.     b := longmul(cbuffer[l1+1]-cbuffer[l2+1],cbuffer[l3]-cbuffer[l2]);
  386.     FaceShown := (a-b) > 0;
  387. end;
  388.  
  389.  
  390. procedure FillShape(x,xsize : integer); assembler;
  391. var
  392.     z1,z2 : byte;
  393.     bitxpos : byte;
  394. asm
  395.     cmp    xsize,200
  396.     jae    @done
  397.     mov    ax,x
  398.     sar    ax,2
  399.     add    ax,display1
  400.     mov    di,ax
  401.  
  402.     lea    si,slope
  403.     mov    ax,x
  404.     mov    cx,ax
  405.     shl    ax,2
  406.     add    si,ax
  407.  
  408.     and    cl,3
  409.     mov    al,$11
  410.     shl    al,cl
  411.     mov    [bitxpos],al
  412.  
  413.     mov    es,SEGA000
  414.     mov    dx,$3C4
  415.     mov    al,$02
  416.     out    dx,al
  417.     cld
  418. @xloop:
  419.     mov    bh,[si+TYPE(slopetype)] {fetch z value}
  420.     lodsw                                    {fetch first xpos}
  421.     mov    dx,ax
  422.     mov    bl,[si+TYPE(slopetype)] {fetch second z value}
  423.     lodsw                                    {fetch second xpos}
  424.     cmp    ax,dx
  425.     jle    @exchange
  426.     xchg    ax,dx
  427.     xchg    bl,bh
  428. @exchange:
  429.     mov    z1,bl
  430.     mov    z2,bh
  431.  
  432.     cmp    dx,0
  433.     jl        @filledout_fast
  434.     cmp    ax,200
  435.     jge    @filledout_fast
  436.     cmp    ax,0
  437.     jge    @cut1
  438.     xor    ax,ax
  439. @cut1:
  440.     cmp    dx,199
  441.     jle    @cut2
  442.     mov    dx,199
  443. @cut2:
  444.     push    si
  445.     push    di
  446.  
  447.     mov    bx,ax                    {find VGA address offset}
  448.     add    bx,bx
  449.     add    di,[OFFSET ytabel+bx]
  450.  
  451.     mov    cx,dx                    {find height of line}
  452.     sub    cx,ax
  453.     jcxz    @filledout
  454.     push    cx
  455.  
  456.     mov    ah,z2                    {prepare z-slope run}
  457.     sub    ah,z1
  458.     xor    al,al
  459.     cwd
  460.     idiv    cx
  461.     mov    bx,ax
  462.  
  463.     mov    dx,$3C5                {set VGA bitplane register}
  464.     mov    al,[bitxpos]
  465.     out    dx,al
  466.  
  467.     mov    ah,z1                {prepare z-slope run}
  468.     xor    al,al
  469.     mov    dx,WIDTH
  470.     pop    cx
  471. @loop:
  472.     add    ax,bx                {add to z-coord run}
  473.     mov    ch,ah                {get z-coord}
  474.     shr    ch,1
  475.     mov    [es:di],ch        {put z-coord on VGA display as colour}
  476.     add    di,dx                {find next VGA line}
  477.     dec    cl
  478.     jnz    @loop
  479.  
  480. @filledout:
  481.     pop    di
  482.     pop    si
  483. @filledout_fast:
  484.     rol    [bitxpos],1
  485.     adc    di,0                    {find next x-position}
  486. @no_address_add:
  487.     dec    xsize
  488.     jnz    @xloop
  489. @done:
  490. end;
  491.  
  492.  
  493. procedure RunOnce;
  494. var
  495.     i : integer;
  496. begin
  497.     SwapDisplay;
  498.     VBLANK;
  499. {$IFDEF DEBUG}
  500.     SetRGB(0,30,0,0);
  501. {$ENDIF}
  502.  
  503.     ClearScreen;
  504.  
  505.     CalcAngle;
  506.     RotateAllCoords;
  507.  
  508.     for i:=1 to NUMBER_FACES do begin
  509.         with face[i] do if FaceShown(l1 SHL 2,l2 SHL 2,l3 SHL 2) then begin
  510.             ClearSlope;
  511.             minx := 200; maxx := 0;
  512.             CalcSlope(l1,l2);
  513.             CalcSlope(l2,l3);
  514.             CalcSlope(l3,l4);
  515.             CalcSlope(l4,l1);
  516.             FillShape(minx, maxx-minx);
  517.         end;
  518.     end;
  519.  
  520. {$IFDEF DEBUG}
  521.     SetRGB(0,0,0,0);
  522.     while KeyHit[26] do ; {Hit 'P' to pause}
  523. {$ENDIF}
  524. end;
  525.  
  526.  
  527. begin
  528.     OpenScreen;
  529.     InitDemo;
  530.     SetAllInterrupts;
  531.     repeat RunOnce until Key='e';
  532.     RestoreAllInterrupts;
  533.     CloseScreen;
  534. end.
  535.